import lxml.etree as ET
import re
from ncclient import manager
from ncclient.operations import RPCError

def netconf_interface_ip(ip,username,password,interface,address,mask,port='830'):
    payload_xml = """
    <config xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
      <native xmlns="http://cisco.com/ns/yang/Cisco-IOS-XE-native">
        <interface>
          <GigabitEthernet>
            <name>2</name>
            <ip>
              <address>
                <primary>
                  <address>10.1.1.2</address>
                  <mask>255.255.255.0</mask>
                </primary>
              </address>
            </ip>
          </GigabitEthernet>
        </interface>
      </native>
    </config>
    """
    interface_name, interface_no = re.match('([a-zA-Z]*)([0-9].*)',interface).groups()
    #print(interface_name,interface_no)
    interface_tag = '{http://cisco.com/ns/yang/Cisco-IOS-XE-native}'+interface_name

    root = ET.fromstring(payload_xml)
    for x in root.iter('{http://cisco.com/ns/yang/Cisco-IOS-XE-native}GigabitEthernet'):
        x.tag = interface_tag
    for x in root.iter(interface_tag):
        for y in x:
            if y.tag == '{http://cisco.com/ns/yang/Cisco-IOS-XE-native}name':
                y.text = interface_no
    for x in root.iter('{http://cisco.com/ns/yang/Cisco-IOS-XE-native}primary'):
        for y in x:
            if y.tag == '{http://cisco.com/ns/yang/Cisco-IOS-XE-native}address':
                y.text = address
            elif y.tag == '{http://cisco.com/ns/yang/Cisco-IOS-XE-native}mask':
                y.text = mask

    print(ET.tostring(root).decode())

    payload_xml = ET.tostring(root).decode()

    with manager.connect(host=ip,
                         port=port,
                         username=username,
                         password=password,
                         timeout=90,
                         hostkey_verify=False,
                         device_params={'name': 'csr'}) as m:



        try:
            response = m.edit_config(target='running', config=payload_xml).xml
            data = ET.fromstring(response.encode())
        except RPCError as e:
            data = e._raw

        # beautify output
        return ET.tostring(data).decode()

if __name__ == '__main__':
    print(netconf_interface_ip('172.16.1.211', 'admin', 'Cisc0123', 'GigabitEthernet3', '20.1.1.1', '255.255.255.0', port='830'))

